//@author A0101878B

#pragma once 

#ifndef Storage_h
#define Storage_h

#include "Task.h"  // need to actualy consider this part of the code later 
//#include "FileHandler"
#include <iostream>
#include <string>
#include <vector>
#include <ctime> 
#include "StatusMessages.h"
#include "FileHandler.h"
#include "DateTime.h"


//#include "DateTime.h"


using namespace std;  

class Storage {
private:
	vector <Task> _floatingTasks;
	vector <Task> _deadlineTasks;
	vector<Task> _timedTasks;

	vector <Task> _duplicatedFloating; 
	vector <Task> _duplicatedDeadline; 
	vector <Task> _duplicatedTimed; 

	vector <Task> _bufferStorage; 
	FileHandler _FileHandler;

public:

	//all the important methods here 
	Storage();

	int displayFromVector (string& output, vector<Task>& vector_task);
	int add(Task toAdd, vector<string>& returnVector);
	int remove(string nameTobeRemoved,vector <string>& returnVector);
	int rename (string nameTobeRenamed, string currentName, vector<string>& oldTask, vector<string>& newTask);  //2 vector 
    int reschedule(string taskName, string newStartTime, string newEndTime, vector<string>& oldTask, vector<string>& newTask); // 2 vectors
	int relocate (string taskName, string newLocation, vector <string>& s1, vector <string>& s2); 

	int mark( string taskName);
	int unmark(string taskName); 

	

	int displayAll(vector<Task>& _temp);

	int displayToday(vector<Task>& _temp);

	int displayStatus(bool done, vector<Task>& _temp);

	bool isExisting(Task& tasktoCheck); 

	////all the search functions 

	//This is to search for task name
	int searchTaskName(string searchTitle, vector<string>& _temp); 
	/*
	int searchTasks(vector<string> keywords, string statusPresent, string type, string start, string end, vector<Task>& _tempStorage);
	*/

	//------------------------------- is implementing this-----
	int searchKeywords(string keywords, vector<Task>& _temp);
	//--------------------------------------------


	int searchEmptySlots(string start, string end, vector<string>& _temp);

    int searchInRange(DateTime& start, DateTime& end, vector<Task>& _temp);
	int searchInRange (string& start, string& end, vector<Task>& _temp);
	int clearAll ();


	int saveFile();
	int loadFile();

	/**

	All the functions that cacn utilize

	**/

	Task& getTask (string name);
	bool isEqual (Task& thisTask, Task& another);

	~Storage();
    vector<string> breakStringintoCombi (string input);

	bool searchTaskobj (vector<Task>& vectorTask, string name, Task*& TaskPtr);
private:
	struct compare {
    bool operator()(const string& first, const string& second) {
        return first.size() > second.size();
    }
};

	void addTask(Task toAdd);
	bool isSuccessfullyRemoved(string nameTobeRemoved,vector<string>& returnVector);
	bool isSuccessfullyMarked(bool mark, Task task);
	void fillVectors(vector<Task>& _temp);

	//No tested
	void matchStatus (bool done, vector<Task>& _temp);

	//------------------- there is no clashing task with the same name 
	//void pushClashing(Task task, vector<Task>& _temp);
	//---------- 


	//
	void setToday(DateTime& start, DateTime& end);
	//

	void loadTasksFromVector(vector<string>& stringsFromFile);

	
	vector<string> taskVecToStringVec(vector<Task>& allTasks);


	//??
	bool isClashWith (Task another);

	////** Deeper level of abstraction, search methods
	////@1
	//Methods for search keywords
	void searchVectors(vector<string> keywords, vector<Task>& _temp);
	void exactMatch(string exactString, vector<Task>& _temp);
	void containMatchFirstWord(string exactString, vector<Task>& _temp);
	void containBrokenDownMatchall(vector<string> keywords, vector<Task>& _temp);

	

	///@2
	//methods for search empty slots
	bool isEmptySlotsPresent(DateTime& start, DateTime& end);
	void matchEmptySlots(DateTime& start, DateTime& end, vector<DateTime>& _temp);
	void cutRangeNTasksOutofBound(DateTime& start, DateTime& end);
	void matchEmptySlotsToTemp(DateTime& start_t, DateTime& end, vector<DateTime>& _temp);



	//to be implemented
	//@3
	void matchInRangeTime(vector<Task>& _temp, DateTime& start, DateTime& end);

	
	vector<string> toStringVector(Task& taskTobeExtracted);
	vector<string> tasktoStringVector  (Task& taskTobeExtracted);

	bool isInRange(DateTime time, DateTime start, DateTime end);


	void setDay(int& day, string& dateTimeString);
	void setMonth(int& month, string& dateTimeString);
	void setYear(int& year, string& dateTimeString);
	void setHour(int& hour, string& dateTimeString);
	void setMin(int& min, string& dateTimeString);
	void setSec(int& sec, string& dateTimeString);
	bool isValidDateTime(int day, int month, int year, int hour, int minute, int sec);

//	bool isInRange(DateTime time, DateTime start, DateTime end);


	//** Lowest level of abstraction//

	bool convertStringStatustoBool (string taskAttribute);


	vector<string> extractKeywords(string str);
	vector<string> stringBrokenDown(string str, char delim);

	string stringToLower(string toLowerString);
	DateTime createDateTimefromString(string input);

//	vector<string> breakStringintoCombi (string input);

};
#endif